***********************************************************************************
*** IVREGCOMPLIER2: PROGRAM FOR CALCULATION OF COMPLIER SHARES & POTENTIAL OUTCOMES
*** AA 2021
*** Builds on code from Manudeep Bhuller for Bhuller et al. 2020 JPE
*** Which in turn builds on
*** ARK's est_PotOutcomes.ado used in this paper previously:
*** Dahl et al. (2014): "Family Welfare Cultures", QJE 129(4), 1711–1752.
***********************************************************************************

quietly {
capture program drop ivregcomplier2
program define ivregcomplier2, eclass
  syntax [if] [, y(varlist) d(varlist) x(string) z(varlist) ///
                 fe(varlist) cluster(varlist) weights(varlist) ///
		 ztrim(real 0) name(string) ]

  marksample touse
  if "`name'" == "" local name __
  capture quietly {	
    gen str ______ = "....Population shares:........."	in 1
    replace ______ = "Pr(Complier)" 			in 2 
    replace ______ = "Pr(Never taker)" 			in 3
    replace ______ = "Pr(Always taker)"	 		in 4
    
    replace ______ = "....Results:..................."	in 5
    replace ______ = "E[Y | D = 0, Complier]" 		in 6
    replace ______ = "E[Y | D = 1, Complier]" 		in 7
    replace ______ = "E[Y(1) - Y(0) | Complier]" 	in 8
    replace ______ = "E[Y | D = 0, Never taker]" 	in 9
    replace ______ = "E[Y | D = 1, Always taker]"	in 10
    replace ______ = "2SLS/IV Estimate"             	in 11
    replace ______ = "2SLS/IV S.E."             	in 12
    replace ______ = "....Extra:....................."	in 13
    replace ______ = "Z(min)"				in 14
    replace ______ = "Z(max)"				in 15
  }

  if "`fe'" == "" { 

  * IV regression using ivreg
  qui ivregress `y' (`d' = `z') `x' if `touse'
  local iv_est = _b[`d']
  local iv_se = _se[`d']

  * We want to do a double residual regression
  tempvar z_r
  qui xtset `fe'
  qui xtreg `z' `x' if `touse', fe
  qui predict `z_r', resid
  qui sum `z' if `touse'
  qui replace `z_r' =  `z_r' + r(mean)
  
  * Do the ztrimming (default is no trimming)
  local upper = 100-`ztrim'
  qui centile `z_r' if `touse', centile(`ztrim' `upper')
  local min = r(c_1)
  local max = r(c_2)
  *qui replace `touse' = `touse'==1 & inrange(`z_r',`min',`max')

  * First stage to get the population shares  
  qui reg `d' `z_r' if `touse'
  local pi_c = _b[`z_r']*(`max'-`min')			// Pop. share compliers
  local pi_a = _b[_cons] + _b[`z_r']*`min'		// Pop. share always takers
  local pi_n = 1 - `pi_c' - `pi_a'			// Pop. share never takers

  * Save some results
  qui cap gen `name' = `pi_c'   if ______=="Pr(Complier)"
  qui replace `name' = `pi_n'   if ______=="Pr(Never taker)"
  qui replace `name' = `pi_a'   if ______=="Pr(Always taker)"
  qui replace `name' = `iv_est' if ______=="2SLS/IV Estimate"
  qui replace `name' = `iv_se'  if ______=="2SLS/IV S.E." 

  * Separate regressions
  qui foreach i in 0 1 {
    reg `y' `z_r' if `touse' & `d'==`i'
    local Y`i'_Z0 	 = _b[_cons] + `min'*_b[`z_r']
    local Y`i'_Z1	 = _b[_cons] + `max'*_b[`z_r']
  }

  * Save some results
  qui replace `name' 	= `Y0_Z1' if ______=="E[Y | D = 0, Never taker]"
  
  local YC0 = `Y0_Z0'*(`pi_c'+`pi_n')/`pi_c' - `Y0_Z1'*(`pi_n'/`pi_c')
  qui replace `name' 	= `YC0' if ______=="E[Y | D = 0, Complier]"

  qui replace `name' 	= `Y1_Z0' if ______=="E[Y | D = 1, Always taker]"
  local YC1 = `Y1_Z1'*(`pi_c'+`pi_a')/`pi_c' - `Y1_Z0'*(`pi_a'/`pi_c')
  qui replace `name' 	= `YC1' if ______=="E[Y | D = 1, Complier]"

  qui replace `name' = `YC1' - `YC0' if ______=="E[Y(1) - Y(0) | Complier]"

  mat PotOut = `pi_c', `pi_n', `pi_a', `YC0', `YC1', `YC1'-`YC0', `Y0_Z1', `Y1_Z0'

  }

  if "`fe'" != "" & "`cluster'" == "" { 

  * IV regression using ivreghfde
  qui ivreghdfe `y' (`d' = `z') `x' if `touse', absorb(`fe')
  local iv_est = _b[`d']
  local iv_se = _se[`d']

  * We want to do a double residual regression
  tempvar z_r
  qui xtset `fe'
  qui xtreg `z' `x' if `touse', fe
  qui predict `z_r', e
  qui sum `z' if `touse'
  qui replace `z_r' =  `z_r' + r(mean)
  
  * Do the ztrimming (default is no trimming)
  local upper = 100-`ztrim'
  qui centile `z_r' if `touse', centile(`ztrim' `upper')
  local min = r(c_1)
  local max = r(c_2)
  *qui replace `touse' = `touse'==1 & inrange(`z_r',`min',`max')

  * First stage to get the population shares  
  qui reg `d' `z_r' if `touse'
  local pi_c = _b[`z_r']*(`max'-`min')			// Pop. share compliers
  local pi_a = _b[_cons] + _b[`z_r']*`min'		// Pop. share always takers
  local pi_n = 1 - `pi_c' - `pi_a'			// Pop. share never takers

  * Save some results
  qui cap gen `name' = `pi_c'   if ______=="Pr(Complier)"
  qui replace `name' = `pi_n'   if ______=="Pr(Never taker)"
  qui replace `name' = `pi_a'   if ______=="Pr(Always taker)"
  qui replace `name' = `iv_est' if ______=="2SLS/IV Estimate"
  qui replace `name' = `iv_se'  if ______=="2SLS/IV S.E." 

  * Separate regressions
  qui foreach i in 0 1 {
    reg `y' `z_r' if `touse' & `d'==`i'
    local Y`i'_Z0 	 = _b[_cons] + `min'*_b[`z_r']
    local Y`i'_Z1	 = _b[_cons] + `max'*_b[`z_r']
  }

  * Save some results
  qui replace `name' 	= `Y0_Z1' if ______=="E[Y | D = 0, Never taker]"
  local YC0 = `Y0_Z0'*(`pi_c'+`pi_n')/`pi_c' - `Y0_Z1'*(`pi_n'/`pi_c')
  qui replace `name' 	= `YC0' if ______=="E[Y | D = 0, Complier]"

  qui replace `name' 	= `Y1_Z0' if ______=="E[Y | D = 1, Always taker]"
  local YC1 = `Y1_Z1'*(`pi_c'+`pi_a')/`pi_c' - `Y1_Z0'*(`pi_a'/`pi_c')
  qui replace `name' 	= `YC1' if ______=="E[Y | D = 1, Complier]"

  qui replace `name' = `YC1' - `YC0' if ______=="E[Y(1) - Y(0) | Complier]"

  mat PotOut = `pi_c', `pi_n', `pi_a', `YC0', `YC1', `YC1'-`YC0', `Y0_Z1', `Y1_Z0'

  }

  if "`fe'" != "" & "`cluster'" != "" &  "`weights'" == "" { 

 /* IV regression using ivreghfde AA we do not need this 
  qui ivreghdfe `y' (`d' = `z') `x' if `touse', absorb(`fe') cluster(`cluster')
  local iv_est = _b[`d']
  local iv_se = _se[`d'] */

  * We want to do a double residual regression
 tempvar z_r 
 * qui xtset `fe'
  *qui xtreg `z' `x' if `touse', fe
    * AA Replaced above two lines with below:
	* AA did some testing that it was identical
  qui reghdfe `z' `x' if `touse', absorb(`fe') cluster(`cluster') resid

  qui predict `z_r', resid

  qui sum `z_r' if `touse' 

  qui replace `z_r'=`z_r'+`r(mean)' 


  * Do the ztrimming (default is no trimming)
  local upper = 100-`ztrim'
  qui centile `z' if `touse', centile(`ztrim' `upper')
  local min = r(c_1)
  local max = r(c_2)
  *qui replace `touse' = `touse'==1 & inrange(`z_r',`min',`max')

  * First stage to get the population shares  
  qui reghdfe `d' `z' `x' if `touse', absorb(`fe') cluster(`cluster')
  local pi_c = _b[`z']*(`max'-`min')			// Pop. share compliers
  local pi_a = _b[_cons] + _b[`z']*`min'		// Pop. share always takers
  local pi_n = 1 - `pi_c' - `pi_a'			// Pop. share never takers

  * Save some results
  qui cap gen `name' = `pi_c'   if ______=="Pr(Complier)"
  qui replace `name' = `pi_n'   if ______=="Pr(Never taker)"
  qui replace `name' = `pi_a'   if ______=="Pr(Always taker)"
  *qui replace `name' = `iv_est' if ______=="2SLS/IV Estimate"
  *qui replace `name' = `iv_se'  if ______=="2SLS/IV S.E." 

  * Separate regressions
  qui foreach i in 0 1 {
    reg `y' `z' if `touse' & `d'==`i'
    local Y`i'_Z0 	 = _b[_cons] + `min'*_b[`z']
    local Y`i'_Z1	 = _b[_cons] + `max'*_b[`z']
  }

  * Save some results
  qui replace `name' 	= `Y0_Z1' if ______=="E[Y | D = 0, Never taker]"
  local YC0 = `Y0_Z0'*(`pi_c'+`pi_n')/`pi_c' - `Y0_Z1'*(`pi_n'/`pi_c')
  qui replace `name' 	= `YC0' if ______=="E[Y | D = 0, Complier]"

  qui replace `name' 	= `Y1_Z0' if ______=="E[Y | D = 1, Always taker]"
  local YC1 = `Y1_Z1'*(`pi_c'+`pi_a')/`pi_c' - `Y1_Z0'*(`pi_a'/`pi_c')
  qui replace `name' 	= `YC1' if ______=="E[Y | D = 1, Complier]"

  qui replace `name' = `YC1' - `YC0' if ______=="E[Y(1) - Y(0) | Complier]"

  mat PotOut = `pi_c', `pi_n', `pi_a', `YC0', `YC1', `YC1'-`YC0', `Y0_Z1', `Y1_Z0'

  }

  if "`fe'" != "" & "`cluster'" != "" &  "`weights'" != "" { 

  * IV regression using ivreghfde
  qui ivreghdfe `y' (`d' = `z') `x' if `touse' [aw=`weights'], absorb(`fe') cluster(`cluster')
  local iv_est = _b[`d']
  local iv_se = _se[`d']

  * We want to do a double residual regression
  tempvar z_r
  qui reghdfe `z' `x' if `touse' [aw=`weights'], absorb(`fe') residuals(`z_r')
  qui sum `z' if `touse'
  qui replace `z_r' =  `z_r' + r(mean)
  
  * Do the ztrimming (default is no trimming)
  local upper = 100-`ztrim'
  qui centile `z_r' if `touse', centile(`ztrim' `upper')
  local min = r(c_1)
  local max = r(c_2)
  *qui replace `touse' = `touse'==1 & inrange(`z_r',`min',`max')

  * First stage to get the population shares  
  qui reg `d' `z_r' if `touse' [aw=`weights']
  local pi_c = _b[`z_r']*(`max'-`min')			// Pop. share compliers
  local pi_a = _b[_cons] + _b[`z_r']*`min'		// Pop. share always takers
  local pi_n = 1 - `pi_c' - `pi_a'			// Pop. share never takers

  * Save some results
  qui cap gen `name' = `pi_c'   if ______=="Pr(Complier)"
  qui replace `name' = `pi_n'   if ______=="Pr(Never taker)"
  qui replace `name' = `pi_a'   if ______=="Pr(Always taker)"
  qui replace `name' = `iv_est' if ______=="2SLS/IV Estimate"
  qui replace `name' = `iv_se'  if ______=="2SLS/IV S.E." 

  * Separate regressions
  qui foreach i in 0 1 {
    reg `y' `z_r' if `touse' & `d'==`i' [aw=`weights']
    local Y`i'_Z0 	 = _b[_cons] + `min'*_b[`z_r']
    local Y`i'_Z1	 = _b[_cons] + `max'*_b[`z_r']
  }

  * Save some results
  qui replace `name' 	= `Y0_Z1' if ______=="E[Y | D = 0, Never taker]"
  local YC0 = `Y0_Z0'*(`pi_c'+`pi_n')/`pi_c' - `Y0_Z1'*(`pi_n'/`pi_c')
  qui replace `name' 	= `YC0' if ______=="E[Y | D = 0, Complier]"

  qui replace `name' 	= `Y1_Z0' if ______=="E[Y | D = 1, Always taker]"
  local YC1 = `Y1_Z1'*(`pi_c'+`pi_a')/`pi_c' - `Y1_Z0'*(`pi_a'/`pi_c')
  qui replace `name' 	= `YC1' if ______=="E[Y | D = 1, Complier]"

  qui replace `name' = `YC1' - `YC0' if ______=="E[Y(1) - Y(0) | Complier]"

  mat PotOut = `pi_c', `pi_n', `pi_a', `YC0', `YC1', `YC1'-`YC0', `Y0_Z1', `Y1_Z0'

  }
  
  ereturn post PotOut, esample(`touse') depname("PotOutcomes")
  ereturn local cmd="bootstrap"
  
  *_____________________________________________________________________________
  * Now print some stuff...
  cap di ".........................................................................."
  cap di "  OUTCOME VARIABLE             : " "`name'" "
  cap di "	Size of compliers            : " `pi_c' " 
  cap di "  Size of never takers         : " `pi_n' "
  cap di "  Size of always takers        : " `pi_a' "
  cap di "  Total size (check)           : " `pi_n' + `pi_a' + `pi_c' "
  cap di "	Potential outcome: Y(1)      : " `YC1' "
  cap di "	Potential outcome: Y(0)      : " `YC0' "
  cap di " 	Implied IV estimate          : " `YC1'-`YC0' "
 * cap di " 	Actual IV estimate           : " `iv_est' "
  * cap di " 	Actual IV standard error     : " `iv_se' "
  cap di "  Trimmed (%)                  : " `ztrim' "
  cap di ""
  
end
} // End quietly 
